package com.simafei.flow.web.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.simafei.flow.web.common.PageUtils;
import com.simafei.flow.web.dao.FlowResultMapper;
import com.simafei.flow.web.domain.req.FlowResultReq;
import com.simafei.flow.web.domain.resp.FlowResultResp;
import com.simafei.flow.web.domain.resp.FrDetailResp;
import com.simafei.flow.web.domain.resp.PageResult;
import com.simafei.flow.web.entity.EdgeResultPO;
import com.simafei.flow.web.entity.FlowPO;
import com.simafei.flow.web.entity.FlowResultPO;
import com.simafei.flow.web.entity.NodeResultPO;
import com.simafei.flow.web.service.IEdgeResultService;
import com.simafei.flow.web.service.IFlowResultService;
import com.simafei.flow.web.service.INodeResultService;
import com.simafei.flow.web.transfer.EdgeResultTransfer;
import com.simafei.flow.web.transfer.NodeResultTransfer;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author fengpengju
 * @since 2024-06-18
 */
@Service
@RequiredArgsConstructor
public class FlowResultServiceImpl extends MPJBaseServiceImpl<FlowResultMapper, FlowResultPO> implements IFlowResultService {

    private final INodeResultService nodeResultService;

    private final IEdgeResultService edgeResultService;

    @Override
    public FlowResultResp getByExecId(String execId) {
        return selectJoinOne(FlowResultResp.class,
                JoinWrappers.lambda(FlowResultPO.class)
                        // 查询主表全部字段
                        .selectAll(FlowResultPO.class)
                        .selectAs(FlowPO::getFlowName, FlowResultResp::getFlowName)
                        .selectAs(FlowPO::getVersionNo, FlowResultResp::getVersionNo)
                        .selectAs(FlowPO::getWeight, FlowResultResp::getWeight)
                        .leftJoin(FlowPO.class, FlowPO::getId, FlowResultPO::getFlowId)
                        .eq(FlowResultPO::getExecId, execId));
    }

    @Override
    public PageResult<FlowResultResp> queryPage(FlowResultReq req) {
        Page<FlowResultResp> page = selectJoinListPage(new Page<>(req.getPageNo(), req.getPageSize()), FlowResultResp.class,
                JoinWrappers.lambda(FlowResultPO.class)
                        // 查询主表全部字段
                        .selectFilter(FlowResultPO.class, e -> !"exec_result".equals(e.getColumn()))
                        .selectAs(FlowPO::getFlowName, FlowResultResp::getFlowName)
                        .selectAs(FlowPO::getVersionNo, FlowResultResp::getVersionNo)
                        .selectAs(FlowPO::getWeight, FlowResultResp::getWeight)
                        .leftJoin(FlowPO.class, FlowPO::getId, FlowResultPO::getFlowId)
                        .eq(req.getExecId() != null, FlowResultPO::getExecId, req.getExecId())
                        .eq(req.getExecStatus() != null, FlowResultPO::getExecStatus, req.getExecStatus())
                        .eq(req.getTestMode() != null, FlowResultPO::getTestMode, req.getTestMode())
                        .eq(req.getExecMode() != null, FlowResultPO::getExecMode, req.getExecMode())
                        .in(CollectionUtil.isNotEmpty(req.getFlowIds()), FlowResultPO::getFlowId, req.getFlowIds())
                        .orderByDesc(FlowResultPO::getCreateTime)
        );
        return PageUtils.buildPageResult(page, page.getRecords());
    }

    @Override
    public FrDetailResp detail(String execId) {
        FrDetailResp vo = new FrDetailResp();

        List<NodeResultPO> details = nodeResultService.list(new LambdaQueryWrapper<>(NodeResultPO.class)
                .eq(NodeResultPO::getExecId, execId));
        vo.setNodeResults(NodeResultTransfer.INSTANCE.toResp(details));

        List<EdgeResultPO> edgeResults = edgeResultService.list(new LambdaQueryWrapper<>(EdgeResultPO.class)
                .eq(EdgeResultPO::getExecId, execId));
        vo.setEdgeResults(EdgeResultTransfer.INSTANCE.toResp(edgeResults));
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void replace(FlowResultPO flowResult) {
        // 这里为了简单先删除再更新，后续可以改成REPLACE或INSERT ON DUPLICATE KEY UPDATE
        remove(new LambdaQueryWrapper<FlowResultPO>()
                .eq(FlowResultPO::getFlowId, flowResult.getFlowId())
                .eq(FlowResultPO::getExecId, flowResult.getExecId()));
        save(flowResult);
    }
}
